#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsItem>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    m_ImgOriginal = new QImage;
    m_Img = new QImage;
    m_ImgSave = new QImage;

    ui->setupUi(this);
    setToolBar();
    //灰度级上下文按钮
    QAction *grayLevel_Button = new QAction(QStringLiteral("grayLevel"), ui->graphicsView);
    ui->graphicsView->addAction(grayLevel_Button);
    ui->graphicsView->setContextMenuPolicy(Qt::ActionsContextMenu);
    connect(grayLevel_Button, &QAction::triggered,this,&MainWindow::drawBarGraph);
    //保存图像上下文按钮
    QAction *saveImg_Button = new QAction(QStringLiteral("saveImg"), ui->graphicsView_2);
    ui->graphicsView_2->addAction(saveImg_Button);
    ui->graphicsView_2->setContextMenuPolicy(Qt::ActionsContextMenu);
    connect(saveImg_Button, &QAction::triggered,
                [=] ()
                {
                    QString fileName = QFileDialog::getSaveFileName(this,tr("Save Image"),"",tr("Images (*.png *.bmp *.jpg)")); //选择路径
                    m_ImgSave->save(fileName);
                });
    ui->label->setText("( 0, 0)");
    //m_ImgFcn = new ImgFcn();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::OpenImg(){
    QString filename;
    filename=QFileDialog::getOpenFileName(this,tr("选择图像"), "",tr("Images (*.png *.bmp *.jpg *.tif *.GIF )"));
    if(filename.isEmpty())  return;
    //加载图像
    m_Img->load(filename);
    m_ImgOriginal = m_Img;
    recvShowPicSignal(m_Img, ui->graphicsView);

    m_Seed = {0,0};
    ui->horizontalSlider->setMaximum(m_Img->width()-1);
    ui->verticalSlider->setMaximum(m_Img->height()-1);

    m_ImgBasicProcessing = new ImgBasicProcessing(m_Img);
    m_ImgDivision = new ImgDivision(m_Img);
    m_ImgMorphology = new ImgMorphology(m_Img);
    m_ImgFcn = new ImgFcn(m_Img);
}

void MainWindow::recvShowPicSignal(QImage*image, QGraphicsView *graphicsView)
{
    m_ImgSave = image;

    QPixmap ConvertPixmap=QPixmap::fromImage(*image);
    int width = ui->graphicsView->width();//获取界面控件Graphics View的宽度
    int height = ui->graphicsView->height();//获取界面控件Graphics View的高度

    qDebug()<<"width="<<width<<" heigth="<<height<<" size="<< ui->graphicsView->size();
    //要用QGraphicsView就必须要有QGraphicsScene搭配着用
    QGraphicsScene  *qgraphicsScene = new QGraphicsScene;
    qgraphicsScene->setSceneRect(QRectF(-width/2,-height/2,width,height));

    qDebug()<<"width="<<width<<" height="<<height;
    //实例化类ImageWidget的对象m_Image，该类继承自QGraphicsItem，是自己写的类
    m_ImgMouseEvents = new ImgMouseEvents(&ConvertPixmap);
    //将界面控件Graphics View的width和height传进类m_Image中
    m_ImgMouseEvents->setQGraphicsViewWH(width,height);

    //将QGraphicsItem类对象放进QGraphicsScene中
    qgraphicsScene->addItem(m_ImgMouseEvents);

    //使视窗的大小固定在原始大小，不会随图片的放大而放大（默认状态下图片放大的时候视窗两边会自动出现滚动条，
    //并且视窗内的视野会变大），防止图片放大后重新缩小的时候视窗太大而不方便观察图片
    graphicsView->setSceneRect(QRectF(-(width/2),-(height/2),width,height));//使视窗的大小固定在原始大小，不会随图片的放大而放大（默认状态下图片放大的时候视窗两边会自动出现滚动条，并且视窗内的视野会变大），防止图片放大后重新缩小的时候视窗太大而不方便观察图片
    //ui->ImageGraphic->setMinimumSize(width,height);
    graphicsView->setScene(qgraphicsScene);
    graphicsView->setFocus();//将界面的焦点设置到当前Graphics View控件
}

void MainWindow::BasicProcessing()
{

    if(m_Img->isNull()) return;

    m_ActionName = QObject::sender()->objectName();

    int delta = slider_InToolBar->value();

    if(QObject::sender()->objectName() == "action_toOriginal") {
        recvShowPicSignal(m_ImgOriginal, ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toGray") {
        recvShowPicSignal(m_ImgBasicProcessing->toGray(), ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toBright") {
        recvShowPicSignal(m_ImgBasicProcessing->toChangeBrightness(delta), ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toWarm") {
        recvShowPicSignal(m_ImgBasicProcessing->toWarmColor(delta), ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toCold") {
        recvShowPicSignal(m_ImgBasicProcessing->toColdColor(delta), ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toSharpen") {
        recvShowPicSignal(m_ImgBasicProcessing->toSharpen(), ui->graphicsView_2);
    }
    if(QObject::sender()->objectName() == "action_toSaturated") {
        recvShowPicSignal(m_ImgBasicProcessing->toChangeSaturation(delta), ui->graphicsView_2);
    }
}

void MainWindow::Division()
{
    if(m_Img->isNull()) return;
    m_ActionName = QObject::sender()->objectName();

    int delta = slider_InToolBar->value();
    //基于阈值
    if(QObject::sender()->objectName() == "action_byThreshold_2") {
        recvShowPicSignal(m_ImgDivision->byThreshold(delta), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byThreshold_Otsu") {
        recvShowPicSignal(m_ImgDivision->byThreshold_Otsu(), ui->graphicsView_2);
        slider_InToolBar->setValue(m_ImgDivision->m_BestThreshold);
    }
    //基于并行算子
    if(m_ActionName == "action_byParallel_Roberts") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Roberts"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Prewitt") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Prewitt"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Sobel") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Sobel"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Laplacian4") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Laplacian4"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Laplacian8") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Laplacian8"), ui->graphicsView_2);
    }
    //基于区域生长
    if(m_ActionName == "action_byRegionGrow4") {
        double newDelta = delta>30.0 ? 30.0 : delta;
        recvShowPicSignal(m_ImgDivision->byRegionGrow(m_Seed, newDelta, 4), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byRegionGrow8") {
        double newDelta = delta>30.0 ? 30.0 : delta;
        recvShowPicSignal(m_ImgDivision->byRegionGrow(m_Seed, newDelta, 8), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byWatershed") {
        recvShowPicSignal(m_ImgDivision->bySLIC(), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byFCN") {
        recvShowPicSignal(m_ImgFcn->imgFCN(), ui->graphicsView_2);
    }
}

void MainWindow::Morphology()
{
    if(m_Img->isNull()) return;
    m_ActionName = QObject::sender()->objectName();

    //形态学
    if(m_ActionName == "action_Morphology_Erosion") {
        recvShowPicSignal(m_ImgMorphology->toErosion(), ui->graphicsView_2);
    }
    if(m_ActionName == "action_Morphology_Expansion") {
        recvShowPicSignal(m_ImgMorphology->toExpansion(), ui->graphicsView_2);
    }

}

void MainWindow::AllProcessing(int delta)
{
    if(m_Img->isNull()) return;
    //基本处理
    /*
    if(m_ActionName == "action_toOriginal") {
        recvShowPicSignal(m_ImgOriginal, ui->graphicsView_2);
    }
    if(m_ActionName == "action_toGray") {
        recvShowPicSignal(m_ImgBasicProcessing->toGray(), ui->graphicsView_2);
    }
    */
    if(m_ActionName == "action_toBright") {
        recvShowPicSignal(m_ImgBasicProcessing->toChangeBrightness(delta), ui->graphicsView_2);
    }
    if(m_ActionName == "action_toWarm") {
        recvShowPicSignal(m_ImgBasicProcessing->toWarmColor(delta), ui->graphicsView_2);
    }
    if(m_ActionName == "action_toCold") {
        recvShowPicSignal(m_ImgBasicProcessing->toColdColor(delta), ui->graphicsView_2);
    }
    /*
    if(m_ActionName == "action_toSharpen") {
        recvShowPicSignal(m_ImgBasicProcessing->toSharpen(), ui->graphicsView_2);
    }
    */
    if(m_ActionName == "action_toSaturated") {
        recvShowPicSignal(m_ImgBasicProcessing->toChangeSaturation(delta), ui->graphicsView_2);
    }

    //分割
    if(m_ActionName == "action_byThreshold_2") {
        recvShowPicSignal(m_ImgDivision->byThreshold(delta), ui->graphicsView_2);
    }
    /*
    if(m_ActionName == "action_byThreshold_Otsu") {
        recvShowPicSignal(m_ImgDivision->byThreshold_Otsu(), ui->graphicsView_2);
        slider_InToolBar->setValue(m_ImgDivision->m_BestThreshold);
    }
    */
    if(m_ActionName == "action_byParallel_Roberts") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Roberts"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Prewitt") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Prewitt"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Sobel") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Sobel"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Laplacian4") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Laplacian4"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byParallel_Laplacian8") {
        recvShowPicSignal(m_ImgDivision->byParallelEdge(delta/255.0, "Laplacian8"), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byRegionGrow4") {
        double newDelta = delta>30.0 ? 30.0 : delta;
        qDebug()<<newDelta;
        recvShowPicSignal(m_ImgDivision->byRegionGrow(m_Seed, newDelta, 4), ui->graphicsView_2);
    }
    if(m_ActionName == "action_byRegionGrow8") {
        double newDelta = delta>30.0 ? 30.0 : delta;
        qDebug()<<newDelta;
        recvShowPicSignal(m_ImgDivision->byRegionGrow(m_Seed, newDelta, 8), ui->graphicsView_2);
    }
    //形态学
    /*
    if(m_ActionName == "action_Morphology_Erosion") {
        recvShowPicSignal(m_ImgMorphology->toErosion(), ui->graphicsView_2);
    }
    if(m_ActionName == "action_Morphology_Expansion") {
        recvShowPicSignal(m_ImgMorphology->toExpansion(), ui->graphicsView_2);
    }
    */
}

void MainWindow::setToolBar()
{
    //水平滑动条
    slider_InToolBar = new QSlider(this);
    slider_InToolBar->setOrientation(Qt::Horizontal);
    slider_InToolBar->setMinimum(0);
    slider_InToolBar->setMaximum(255);
    slider_InToolBar->setValue(30);
    slider_InToolBar->setSingleStep(1);
    slider_InToolBar->setMaximumWidth(255);
    //显示值 标签
    QLabel *label_InToolBar = new QLabel();
    label_InToolBar->setNum(30);

    //重载方式添加信号回调
    connect(slider_InToolBar, &QAbstractSlider::sliderPressed,
                [=] ()
                {
                    label_InToolBar->setNum(slider_InToolBar->value());
                    AllProcessing(slider_InToolBar->value());
                });
    connect(slider_InToolBar, &QAbstractSlider::sliderMoved,
                [=] ()
                {
                    label_InToolBar->setNum(slider_InToolBar->value());
                    AllProcessing(slider_InToolBar->value());
                } );
    connect(slider_InToolBar, &QAbstractSlider::valueChanged,
                [=] ()
                {
                    label_InToolBar->setNum(slider_InToolBar->value());
                    AllProcessing(slider_InToolBar->value());
                });

    //工具栏添加控件、分割线
    ui->mainToolBar->addWidget(slider_InToolBar);
    ui->mainToolBar->addSeparator();  //插入分隔线
    ui->mainToolBar->addWidget(label_InToolBar);
    ui->mainToolBar->addSeparator();  //插入分隔线
}

void MainWindow::drawBarGraph()
{
    //https://blog.csdn.net/weixin_42837024/article/details/82257021
    if(m_Img->isNull()) return;

    int grayLevel[256];
    for (int i = 0; i < 256; i++) {
        grayLevel[i] = m_ImgDivision->m_GrayLevel[i];
    }

//![3]
    QBarSeries *series = new QBarSeries();
    for (int i = 0; i < 256; i++) {
        QBarSet *set = new QBarSet(QString(i));
        *set<<grayLevel[i];
        series->append(set);
    }

    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("gray level value");
    chart->setAnimationOptions(QChart::SeriesAnimations);

//![4]
    QStringList categories;
    categories << "img" ;
    QBarCategoryAxis *axis = new QBarCategoryAxis();
    axis->append(categories);
    chart->createDefaultAxes();//创建默认的左侧的坐标轴（根据 QBarSet 设置的值）
    chart->setAxisX(axis, series);//设置坐标轴
//![4]

//![5]
    chart->legend()->setVisible(false); //设置图例为显示状态
    chart->legend()->setAlignment(Qt::AlignBottom);//设置图例的显示位置在底部
//![5]

//![6]
    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartView->show();

    //QGraphicsScene  *qgraphicsScene = new QGraphicsScene;
    //qgraphicsScene->addItem(chart);
    //ui->graphicsView_2->setScene(qgraphicsScene);
}

void MainWindow::getSliderSeed()
{
    if(m_Img->isNull()) return;

    int y = m_Img->height()-1 - ui->verticalSlider->value();
    int x = ui->horizontalSlider->value();

    QImage *newImg = new QImage(m_Img->width(), m_Img->height(), QImage::Format_ARGB32);
    for(int yy = 0; yy<m_Img->height(); yy++)
    {
        QRgb * line = (QRgb *)m_Img->scanLine(yy);
        for(int xx = 0; xx<m_Img->width(); xx++)
        {
            newImg->setPixel(xx,yy, qRgb(qRed(line[xx]), qGreen(line[xx]), qBlue(line[xx])));
        }
    }

    for (int i = 0; i<m_Img->width(); i++) {
        newImg->setPixel(i, y, qRgb(255, 0, 255));
    }
    for (int i = 0; i<m_Img->height(); i++) {
        newImg->setPixel(x, i, qRgb(255, 0, 255));
    }
    recvShowPicSignal(newImg, ui->graphicsView);
    m_Seed = {x, y, 0};
    ui->label->setText("( "+QString::number(x)+","+QString::number(y)+")");
}

void MainWindow::ImgChanged()
{
    if(m_Img->isNull()) return;
    m_Img = m_ImgSave;
    recvShowPicSignal(m_Img, ui->graphicsView);

    m_Seed = {0,0};
    ui->horizontalSlider->setMaximum(m_Img->width()-1);
    ui->verticalSlider->setMaximum(m_Img->height()-1);

    m_ImgBasicProcessing = new ImgBasicProcessing(m_Img);
    m_ImgDivision = new ImgDivision(m_Img);
    m_ImgMorphology = new ImgMorphology(m_Img);

}

void MainWindow::ImgChangedToR()
{
    if(m_Img->isNull()) return;
    recvShowPicSignal(m_Img, ui->graphicsView_2);
}
/*
void MainWindow::ShowSliderValue()
{
    //显示含有滑动条值的标签
    int width =  ui->hSlider_ForDelta->width();
    int value = ui->hSlider_ForDelta->value();
    //当前值，对应在滑动条长度范围里的 长度(百分比)
    double labelX = ui->hSlider_ForDelta->x() + (value + 255.0) / 255.0 /2.0 * width;
    qDebug()<<labelX;
    //设置标签的大小
    m_SliderLabel->setFixedSize(QSize(30,30));
    //设置游标背景为白色， 设置无边框透明
    m_SliderLabel->setWindowFlags(Qt::FramelessWindowHint);//无边框
    m_SliderLabel->setAttribute(Qt::WA_TranslucentBackground);//背景透明
    //m_SliderLabel->setAutoFillBackground(true);
    //QPalette palette;
    //palette.setColor(QPalette::Background, Qt::white);
    //m_SliderLabel->setPalette(palette);
    //m_SliderLabel->setFrameStyle(QFrame::HLine | QFrame::Sunken);

    m_SliderLabel->setAlignment(Qt::AlignCenter);
    m_SliderLabel->setNum(value);
    m_SliderLabel->move(labelX + 365, ui->hSlider_ForDelta->y() +230);
    //m_SliderLabel->setVisible(true);

    //33按下  34移动  35 释放
    switch (QObject::senderSignalIndex()) {
        case 33:
            qDebug()<<"on";
            m_SliderLabel->setVisible(true);
            break;
        case 34:
            qDebug()<<"move";
            m_SliderLabel->setVisible(true);
            break;
        case 35:
            qDebug()<<"release";
            m_SliderLabel->setVisible(false);
            return;
            //break;
    }
}
*/
